﻿#region [ License information          ]
/* ************************************************************
 *
 * Copyright (c) Bjørn Bouet Smith, 2012
 *
 * This source code is subject to terms and conditions of 
 * Microsoft Public License (Ms-PL).
 * 
 * A copy of the license can be found in the license.txt
 * file at the root of this distribution. If you can not 
 * locate the License, please send an email to bjornsmith@gmail.com
 * 
 * By using this source code in any fashion, you are 
 * agreeing to be bound by the terms of the Microsoft 
 * Public License.
 *
 * You must not remove this notice, or any other, from this
 * software.
 *
 * ************************************************************/
#endregion

using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace Smith.BuildExtensions.ConfigurationTransformation
{
    /// <summary>
    /// class that will return all "keys" or variable names from a given input string.
    /// </summary>
    public class KeyReader : IKeyReader
    {
        const string Regex = @"(?:\<\!\[CDATA\[)?\s*\$\((?<Key>[^)]*)\)\s*(?:]]>)|\$\((?<Key>[^)]*)\)|\<\!\-\-\s*\$\((?<Key>[^)]*)\)\s*\-\-\>";
        public static readonly Regex KeyRegex = new Regex(Regex, RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace | RegexOptions.IgnoreCase);

        /// <summary>
        /// Gets the keys from the given input string
        /// </summary>
        /// <param name="inputString">The input string.</param>
        /// <returns>The list of keys contained in the string.</returns>
        /// <exception cref="ArgumentNullException">If the inputstring is null</exception>
        public ICollection<string> GetKeys(string inputString)
        {
            if (inputString == null)
            {
                throw new ArgumentNullException("inputString");
            }

            List<string> keys = new List<string>();
        
            foreach (Match m in KeyRegex.Matches(inputString))
            {
                Group g = m.Groups["Key"];
                if (!keys.Contains(g.Value))
                {
                    keys.Add(g.Value);
                }
            }

            return keys;
        }
    }
}
